/**
 * @file {数据清洗} AOI  --->   Line DB
 * @desc 数据清洗逻辑见 README.txt
 */
'use strict'

const schedule = require('node-schedule');
const LRU = require("lru-cache");
// 每一个工站的库实例化
const SynchronizeCfJingdu = require('../class/jingdujiance/cf_jingdu');
const SynchronizeTftJingdu = require('../class/jingdujiance/tft_jingdu');
const SynchronizeCfPol = require('../class/pol/cf_pol');
const SynchronizeTftPol = require('../class/pol/tft_pol');
const SynchronizePiantieqian = require('../class/piantie/piantieqian');
const SynchronizePiantiehou = require('../class/piantie/piantiehou');
const SynchronizeMujian = require('../class/summary');

const {
    piantieqian_db_config,
    piantiehou_db_config,
    cf_pol_db_config,
    tft_pol_db_config,
    cf_jingdujiance_db_config,
    tft_jingdujiance_db_config,
} = require('../config.json').station_db; // 源库
const {
    linedb_piantiehou_config,
    linedb_piantieqian_config,
    linedb_cf_pol_config,
    linedb_tft_pol_config,
    linedb_cf_jingdujiance_config,
    linedb_tft_jingdujiance_config,
    linedb_summary_config,
} = require('../config.json').line_db; // 目标库

// sequlize 实例
const seq_src_cf_jingdu = require('../lib/db').get_instance(cf_jingdujiance_db_config).sequelize;
const seq_aim_cf_jingdu = require('../lib/db').get_instance(linedb_cf_jingdujiance_config).sequelize;
const seq_src_tft_jingdu = require('../lib/db').get_instance(tft_jingdujiance_db_config).sequelize;
const seq_aim_tft_jingdu = require('../lib/db').get_instance(linedb_tft_jingdujiance_config).sequelize;

const seq_src_cf_pol = require('../lib/db').get_instance(cf_pol_db_config).sequelize;
const seq_aim_cf_pol = require('../lib/db').get_instance(linedb_cf_pol_config).sequelize;
const seq_src_tft_pol = require('../lib/db').get_instance(tft_pol_db_config).sequelize;
const seq_aim_tft_pol = require('../lib/db').get_instance(linedb_tft_pol_config).sequelize;

const seq_src_piantieqian = require('../lib/db').get_instance(piantieqian_db_config).sequelize;
const seq_aim_piantieqian = require('../lib/db').get_instance(linedb_piantieqian_config).sequelize;
const seq_src_piantiehou = require('../lib/db').get_instance(piantiehou_db_config).sequelize;
const seq_aim_piantiehou = require('../lib/db').get_instance(linedb_piantiehou_config).sequelize;

const seq_aim_summary = require('../lib/db').get_instance(linedb_summary_config).sequelize;
// 精度检测工位表实例
const {PanelJingdu} = require('../model/jingdujiance/panel');
// pol 工位表实例
const {FlawPol} = require('../model/pol/flaw');
const {FlawFilterPol} = require('../model/pol/flaw_filter');
const {PanelPol} = require('../model/pol/panel');
const {JobPol} = require('../model/pol/job');
// 偏贴
const {FlawPiantie} = require('../model/piantie/flaw');
const {FlawFilterPiantie} = require('../model/piantie/flaw_filter');
const {PanelPiantie} = require('../model/piantie/panel');
const {JobPiantie} = require('../model/piantie/job');
// 目检
const {PanelMujian} = require('../model/summary/panel_summary');
const {FlawFilterMujian} = require('../model/summary/flaw_filter');
const {FlawMujian} = require('../model/summary/flaw');
const options = {
    max: 500,
    length: function (n, key) { return n * 2 + key.length },
    dispose: function (key, n) { n.close() }, 
    maxAge: 1000 * 60 * 60
}
class CacheData {

    constructor() {
        // 初始化缓存
        this.cache = new LRU(options);;
         // 目检
         this.mujian = SynchronizeMujian.getInstance({PanelMujian, FlawFilterMujian, FlawMujian}, seq_aim_summary, '汇总');
        // 精度检测站
        // this.cf_jingdu = SynchronizeCfJingdu.getInstance(PanelJingdu, seq_src_cf_jingdu, seq_aim_cf_jingdu, 'CF 精度检测');
        // this.tft_jingdu = SynchronizeTftJingdu.getInstance(PanelJingdu, seq_src_tft_jingdu, seq_aim_tft_jingdu, 'TFT 精度检测');
        // POL站
        this.cf_pol = SynchronizeCfPol.getInstance({FlawPol, FlawFilterPol, PanelPol, JobPol}, seq_src_cf_pol, seq_aim_cf_pol, 'CF_POL工位', this.mujian);
        this.tft_pol = SynchronizeTftPol.getInstance({FlawPol, FlawFilterPol, PanelPol, JobPol}, seq_src_tft_pol, seq_aim_tft_pol, 'TFTPOL工位', this.mujian);
        // 偏贴站
        this.piantieqian = SynchronizePiantieqian.getInstance({FlawPiantie, FlawFilterPiantie, PanelPiantie, JobPiantie}, seq_src_piantieqian, seq_aim_piantieqian, '偏贴前工位', this.mujian);
        this.piantiehou = SynchronizePiantiehou.getInstance({FlawPiantie, FlawFilterPiantie, PanelPiantie, JobPiantie}, seq_src_piantiehou, seq_aim_piantiehou, '偏贴后工位', this.mujian);

        this.getAllStationInfo();
        process.on('message', async (msg) => {
            const { port, panelId} = msg;
            // 缓存命中
            if (this.cache.get(panelId)) {
                process.send({port, info: this.cache.get(panelId)});
            } else {
               let res = await this.getAllStationInfoByPanelId(panelId);
               process.send({port, info: res});
            }
        })
    }
    /**
     * 开启缓存轮询
     */
    getAllStationInfo () {
        const job = schedule.scheduleJob( '*/2 * * * * *', async () => {
            // loop偏贴后工站的panel, 有新的片出来，就把全部信息查出来，存进缓存
           let curentPanel = await this.piantiehou.getNewsPanel();
           if (curentPanel) {
                this.getAllStationInfoByPanelId(curentPanel);
           }
        });
    }
    /**
     * 汇总各个工站数据
     * @param {String} panelId
     */
    async getAllStationInfoByPanelId (panelId) {
        let piantieqian_info = await this.piantieqian.getNewstInfoByPanelId(panelId);
        let cf_pol_info = await this.cf_pol.getNewstInfoByPanelId(panelId);
        let tft_pol_info = await this.tft_pol.getNewstInfoByPanelId(panelId);
        let piantiehou_info = await this.piantiehou.getNewstInfoByPanelId(panelId);
        // let mujian_info = await this.mujian.getNewstInfoByPanelId(panel)
        let summaryData = JSON.stringify({
            piantieqian: {
                ...piantieqian_info
            },
            cf_pol: {
                ...cf_pol_info
            },
            tft_pol: {
                ...tft_pol_info
            },
            piantiehou: {
                ...piantiehou_info
            },
        })
        this.cache.set(panelId, summaryData);
        return summaryData;
    }
    static getInstance () {
        return CacheData.instance ? CacheData.instance : new CacheData();
    }
}
CacheData.getInstance();